<template>
  <div class="statistics-sso">
    <div class="statistics-sso__panel">
      <div class="statistics-sso__spinner"></div>
      <p class="statistics-sso__title">正在完成单点登录</p>
      <p class="statistics-sso__message">{{ message }}</p>
    </div>
  </div>
</template>

<script>
import { codeLogin } from '@/api/system/sso'
import { setToken, getToken } from '@/utils/auth'

const DEFAULT_TARGET_PATH = '/statistics/statistics'

export default {
  name: 'StatisticsSso',
  data() {
    return {
      message: '正在校验授权信息，请稍候...',
      redirectUri: process.env.VUE_APP_SSO_REDIRECT_URI,
      targetPath: DEFAULT_TARGET_PATH
    }
  },
  created() {
    this.handleCallback()
  },
  methods: {
    /**
     * 处理授权回调整体流程：
     * 1. 已登录但无 code：直接进入目标页；
     * 2. 携带 code：调用后端完成换取；
     * 3. 其他情况：跳转用户中心发起授权。
     */
    async handleCallback() {
      debugger
      const { code, state, error, error_description: errorDescription } = this.$route.query
      this.targetPath = this.resolveTargetPath(state)

      if (getToken() && !code) {
        this.message = '已登录，正在跳转目标页面...'
        this.$router.replace(this.targetPath)
        return
      }

      if (error) {
        const finalMsg = decodeURIComponent(errorDescription || error)
        this.message = finalMsg || '授权失败，请稍后重试'
        this.delayToAuthorize()
        return
      }
      console.log("code: ",code)
      if (!code) {
        this.redirectToAuthorize()
        return
      }

      await this.exchangeToken(code)
    },
    /**
     * 根据 state 计算落地页，只允许站内地址
     */
    resolveTargetPath(state) {
      if (!state) {
        return DEFAULT_TARGET_PATH
      }
      let decoded = state
      try {
        decoded = decodeURIComponent(state)
      } catch (e) {
        decoded = state
      }
      if (!decoded || decoded === '/' || decoded === this.redirectUri || decoded.startsWith('/login')) {
        return DEFAULT_TARGET_PATH
      }
      if (decoded.startsWith('/')) {
        return decoded
      }
      return DEFAULT_TARGET_PATH
    },
    /**
     * 使用授权码换取本系统 token
     */
    async exchangeToken(code) {
      try {
        this.message = '授权码校验中，请稍候...'
        debugger
        //const encodedRedirect = encodeURIComponent(this.redirectUri)
        console.log(code)
        const response = await codeLogin(code, this.redirectUri)
        const localToken = response.token
        if (!localToken) {
          throw new Error('未能获取本系统 token')
        }
        setToken(localToken)
        this.$store.commit('SET_TOKEN', localToken)
        this.message = '授权成功，正在跳转目标页面...'
        setTimeout(() => {
          this.$router.replace(this.targetPath)
        }, 600)
      } catch (error) {
        const finalMsg = error?.msg || error?.message || '授权失败，请稍后重试'
        this.message = finalMsg
        this.delayToAuthorize()
      }
    },
    /**
     * 构建授权地址
     */
    buildAuthorizeUrl(statePath = DEFAULT_TARGET_PATH) {
      const serverUrl = process.env.VUE_APP_SSO_SERVER_URL
      const appCode = process.env.VUE_APP_SSO_APP_CODE
      const clientId = process.env.VUE_APP_SSO_CLIENT_ID
      const scope = process.env.VUE_APP_SSO_SCOPE || 'openid phone profile'
      if (!serverUrl || !appCode || !clientId) {
        throw new Error('用户中心配置缺失，请配置 VUE_APP_SSO_SERVER_URL / APP_CODE / CLIENT_ID')
      }
      const encodedRedirect = encodeURIComponent(this.redirectUri)
      const encodedState = encodeURIComponent(statePath)
      const base = serverUrl.replace(/\/$/, '')
      const url =  `${base}/v1/authorize/${appCode}/oauth2/auth?response_type=code&client_id=${clientId}&scope=${encodeURIComponent(scope)}&state=${encodedState}&redirect_uri=${encodedRedirect}`
      console.log("url: ",url)
      return url
    },
    /**
     * 无 code 或异常时跳转至用户中心
     */
    redirectToAuthorize() {
      this.message = '正在跳转到统一身份认证，请稍候...'
      const authorizeUrl = this.buildAuthorizeUrl(this.targetPath)
      window.location.href = authorizeUrl
    },
    delayToAuthorize() {
      setTimeout(() => {
        this.redirectToAuthorize()
      }, 1200)
    }
  }
}
</script>

<style lang="scss" scoped>
.statistics-sso {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: radial-gradient(circle at top, #041833 0%, #01060f 65%, #000000 100%);
  color: #e6f7ff;

  &__panel {
    width: 360px;
    padding: 40px 30px;
    text-align: center;
    border-radius: 16px;
    background: rgba(7, 22, 47, 0.85);
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
    border: 1px solid rgba(91, 207, 220, 0.3);
  }

  &__spinner {
    width: 72px;
    height: 72px;
    margin: 0 auto 24px;
    border-radius: 50%;
    border: 4px solid rgba(91, 207, 220, 0.2);
    border-top-color: #5bcfdc;
    animation: spin 1s linear infinite;
  }

  &__title {
    font-size: 20px;
    font-weight: bold;
    margin-bottom: 12px;
    letter-spacing: 1px;
  }

  &__message {
    font-size: 14px;
    color: #9fd7ff;
  }
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>
